package com.sks.web.action.uploadfile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;
import org.apache.struts.upload.MultipartRequestHandler;
import org.springframework.stereotype.Controller;

import com.sks.bean.PageView;
import com.sks.bean.pojo.SysInfo;
import com.sks.bean.uploadfile.UploadFile;
import com.sks.core.SystemConstants;
import com.sks.service.base.SysInfoService;
import com.sks.service.uploadfile.UploadFileService;
import com.sks.utils.ConfigInfo;
import com.sks.utils.FileUtil;
import com.sks.utils.ImageSizer;
import com.sks.utils.StringUtil;
import com.sks.utils.WebUtil;
import com.sks.web.action.BasicAction;
import com.sks.web.action.privilege.Permission;
import com.sks.web.formbean.uploadfile.UploadfileForm;

@Controller("/cms/uploadFile")
public class UploadFileAction extends BasicAction {
	protected static Log log = LogFactory.getLog(UploadFileAction.class);

	private static String uploadDir = null;

	@Resource(name = "uploadFileServiceBean")
	private UploadFileService uploadFileService;
	@Resource(name = "sysInfoServiceBean")
	private SysInfoService sysInfoService;
	
	@Permission(module = "house", privilege = "view")
	public ActionForward listH(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return list(mapping, form, request, response);
	}
	
	@Permission(module = "house", privilege = "view")
	public ActionForward listVideo(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return listV(mapping, form, request, response);
	}
	
	@Permission(module = "building", privilege = "view")
	public ActionForward listB(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return list(mapping, form, request, response);
	}

	private ActionForward listV(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		UploadfileForm formbean = (UploadfileForm) form;
		PageView<UploadFile> pageView = new PageView<UploadFile>(12, formbean
				.getPage());
		int firstindex = (pageView.getCurrentpage() - 1) * pageView.getMaxresult();
		StringBuffer sb = new StringBuffer(" o.objType = ? and o.objId = ? and o.extension not in ('png','gif','jpg')");
		LinkedHashMap<String, String> orderby = new LinkedHashMap<String, String>();
		orderby.put("fileId", "asc");
		pageView.setQueryResult(uploadFileService.getScrollData(firstindex, pageView.getMaxresult(),
				sb.toString(), new Object[]{formbean.getObjType(), formbean.getObjId()}, orderby));
		request.setAttribute("pageView", pageView);
		return mapping.findForward("listv");
	}
	
	private ActionForward list(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		UploadfileForm formbean = (UploadfileForm) form;
		PageView<UploadFile> pageView = new PageView<UploadFile>(12, formbean
				.getPage());
		int firstindex = (pageView.getCurrentpage() - 1) * pageView.getMaxresult();
		StringBuffer sb = new StringBuffer(" o.objType = ? and o.objId = ? and o.extension in ('png','gif','jpg')");
		LinkedHashMap<String, String> orderby = new LinkedHashMap<String, String>();
		orderby.put("fileId", "asc");
		pageView.setQueryResult(uploadFileService.getScrollData(firstindex, pageView.getMaxresult(),
				sb.toString(), new Object[]{formbean.getObjType(), formbean.getObjId()}, orderby));
		request.setAttribute("pageView", pageView);
		return mapping.findForward("list");
	}

	@Permission(module = "house", privilege = "upload")
	public ActionForward uploadUIH(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return uploadUI(mapping, form, request, response);
	}
	
	@Permission(module = "building", privilege = "upload")
	public ActionForward uploadUIB(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return uploadUI(mapping, form, request, response);
	}
	
	private ActionForward uploadUI(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return mapping.findForward("upload");
	}
	
	@Permission(module = "house", privilege = "upload")
	public ActionForward uploadVideoUI(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return mapping.findForward("uploadv");
	}
	
	@Permission(module = "house", privilege = "upload")
	public ActionForward saveTempFileH(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return saveTempFile(mapping, form, request, response);
	}
	
	@Permission(module = "building", privilege = "upload")
	public ActionForward saveTempFileB(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return saveTempFile(mapping, form, request, response);
	}

	private ActionForward saveTempFile(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		//判断是否超出大小
		boolean maxLengthExceeded = StringUtil.toBoolean(request.getAttribute(MultipartRequestHandler.ATTRIBUTE_MAX_LENGTH_EXCEEDED), false);
		if (maxLengthExceeded) {
			response.getWriter().write("{\"success\":false, \"msg\":\"" + this.getMessage("errors.upload.MaxLengthExceeded", ConfigInfo.getValue("MaxUploadFileSize")) + "\"}");
			return null;
		}
		UploadfileForm formbean = (UploadfileForm) form;
		Hashtable formFilesTable = formbean.getMultipartRequestHandler()
				.getFileElements();
		Enumeration en = formFilesTable.keys();

		FormFile formFile = null;
		//String srcFileName = null;
		//BufferedInputStream bis = null;
		//BufferedOutputStream bos = null;

		UploadFile uf = new UploadFile();

		if (en.hasMoreElements()) {
			formFile = (FormFile) formFilesTable.get(en.nextElement());
		}

		if (null == formFile) {
			throw new Exception("upload file is null");
		}

		//srcFileName = formFile.getFileName();
		String saveName = new Date().getTime() + UUID.randomUUID().toString();
		String ext = UploadfileForm.getExt(formFile);//srcFileName.substring(srcFileName.indexOf(".") + 1);
		
		if (!checkExtention(ext)) {
			response.getWriter().write("{\"success\":false, \"msg\":\"" + this.getMessage("errors.upload.NotAllowType") + "\"}");
			return null;
		}

		setTempDir(request);
		String tempDir = uploadDir + UploadFile.SLASH + formbean.getObjType()
				+ UploadFile.SLASH + formbean.getObjId();
		if (!FileUtil.createDir(tempDir)) {
			RuntimeException e = new RuntimeException("create dir faild");
			log.error("create dir faild", e);
			throw e;
		}

		try {
			/*bos = new BufferedOutputStream(new FileOutputStream(new File(
					tempDir, saveName + "." + ext)));
			bis = new BufferedInputStream(formFile.getInputStream());
			byte[] buffer = new byte[4096];
			int count = -1;
			while ((count = bis.read(buffer)) > 0) {
				bos.write(buffer, 0, count);
			}
			buffer = null;*/
			if("swf".equalsIgnoreCase(ext)){
				saveFile(tempDir, saveName + "." + ext, formFile.getInputStream(), false);
			}else{
				saveFile(tempDir, saveName + "." + ext, formFile.getInputStream(), true);
			}
			
			
			
			uf.setPath("upload" + UploadFile.SLASH + formbean.getObjType() + UploadFile.SLASH + formbean.getObjId());
			uf.setName(saveName);
			uf.setUploadTime(new Date());
			uf.setExtension(ext);
			uf.setFileId(null);
			uf.setObjId(formbean.getObjId());
			uf.setObjType(formbean.getObjType());
			
			uploadFileService.save(uf);
			
			response.getWriter().write("{\"success\":true}");
		} catch (Exception ex) {
			response.getWriter().write("{\"success\":false, \"msg\":\"unknown\"}");
			log.error(ex.getMessage(), ex);
		}
		return null;
	}
	
	private static boolean checkExtention(String ext) throws Exception {
		if (StringUtil.isEmpty(ext) || !WebUtil.isAllowImagesType(ext)) {
			throw new Exception("extention is null or invalidate");
		}
		return true;
	}

	@Permission(module = "house", privilege = "upload")
	public ActionForward deleteH(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return delete(mapping, form, request, response);
	}
	
	@Permission(module = "building", privilege = "upload")
	public ActionForward deleteB(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return delete(mapping, form, request, response);
	}

	private ActionForward delete(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		UploadfileForm formbean = (UploadfileForm) form;
		uploadFileService.delete(request.getSession().getServletContext().getRealPath("/"), (Serializable[])formbean.getFileIds());
		return list(mapping, formbean, request, response);
	}
	
	@Permission(module = "house", privilege = "upload")
	public ActionForward deleteV(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return deleteVideo(mapping, form, request, response);
	}
	
	private ActionForward deleteVideo(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		UploadfileForm formbean = (UploadfileForm) form;
		uploadFileService.delete(request.getSession().getServletContext().getRealPath("/"), (Serializable[])formbean.getFileIds());
		return listV(mapping, formbean, request, response);
	}
	
	private void setTempDir(HttpServletRequest request) throws Exception {
		if (null == uploadDir) {
		   SysInfo si = sysInfoService.get(SystemConstants.SYS_INFO_KEY_UPLOAD_FILE_DIR);
		   uploadDir = si.getValue() + "/upload/";
		}
	}
	
	private File saveFile(String savedir, String fileName, InputStream ins, boolean needCompress)
			throws Exception {
		File dir = new File(savedir);
		if (!dir.exists()) {
			dir.mkdirs();// 如果目录不存在就创建
		}
		File file = new File(savedir, fileName);
		FileOutputStream fileoutstream = new FileOutputStream(file);
		
		byte[] buffer = new byte[4096];
		int count = -1;
		while ((count = ins.read(buffer)) > 0) {
			fileoutstream.write(buffer, 0, count);
		}
		buffer = null;
		fileoutstream.close();
		//ins.close();
		
		if (needCompress) {
			try {
				File resizedDir = new File(savedir + UploadFile.SLASH
						+ UploadFile.SMALL_SIZE + UploadFile.SLASH);
				if (!resizedDir.exists()) {
					resizedDir.mkdirs();
				}
				File resizedFile = new File(resizedDir, fileName);
				ImageSizer.resize(file, resizedFile, UploadFile.SMALL_SIZE,
						UploadfileForm.getExt(fileName));
			} catch (Exception e) {
				log.error("压缩文件失败", e);
			}
		}
		return file;
	}
}
